package com.gzist.security4.web.manage;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gzist.security4.domain.Permission;
import com.gzist.security4.mapper.PermissionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.function.Supplier;

/**
 * 自定义动态授权管理器
 *  新版本使用
 * @author: 黄泽建
 */
@Component
@Slf4j
public class SttAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext requestAuthorizationContext) {
        String uri = requestAuthorizationContext.getRequest().getRequestURI();
        log.info("访问路径=====》{}", uri);
        // 对于登录注册退出这些访问公共权限一致放行
        if (uri.equals("/") || uri.equals("/user/login") || uri.equals("logout") || uri.equals("error")) {
            return new AuthorizationDecision(true);
        }

        // 根据当前访问路径去查询相应权限
        Permission permission = permissionMapper.selectOne(new QueryWrapper<Permission>().eq("path", uri.replaceFirst("/", "")));
        log.info("路径权限=====》{}", permission);
        if (permission == null) {
            //当没找到对应权限的时候，说明资源上的权限发生了相应的更改，需要拦截下来进行告知说明，至于该如何做后面具体再考虑
            return new AuthorizationDecision(false);
        }
        String perms = permission.getPerms();
        if (perms == null || perms.trim().equals("")) {
            // 当前访问路径存在而权限标识为空这一般是对于那些公共的按钮组件，均给放行
            return new AuthorizationDecision(true);
        }
        // 根据当前访问资源的权限来判断存否与当前用户的所有权限中
        Collection<? extends GrantedAuthority> authorities = authentication.get().getAuthorities();
        for (GrantedAuthority authority : authorities) {
            String s = authority.getAuthority();
            if (s.equals(perms)) {
                // 循环遍历如果相等则说明有这权限
                return new AuthorizationDecision(true);
            }
        }

        // 最后但上面情况都没有发生，便剩下最后一种情况就是当前用户没有访问当前接口的权限
        return new AuthorizationDecision(false);
    }
}
